package com.linjiang.server.transactional;

import com.alibaba.fastjson.JSONObject;
import com.linjiang.server.netty.NettyClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 分布式事务管理器
 */
@Component
public class GlobalTransactionManager {


    private static NettyClient nettyClient;

    /**
     * 当前线程的分支事务
     */
    private static ThreadLocal<BatchTransaction> currentBatchTransaction = new ThreadLocal<>();

    /**
     * 当前线程的全局事务组id
     */
    private static ThreadLocal<String> currentGroupId = new ThreadLocal<>();

    /**
     * 当前线程的分支事务数
     */
    private static ThreadLocal<Integer> transactionCount = new ThreadLocal<>();

    @Autowired
    public void setNettyClient(NettyClient nettyClient) {
        GlobalTransactionManager.nettyClient = nettyClient;
    }

    public static Map<String, BatchTransaction> BATCH_TRANSACION_MAP = new HashMap<>();

    /**
     * 创建全局分布式事务组，并且返回groupId
     * @return
     */
    public static String createGlobalTransactionGroup() {
        String groupId = UUID.randomUUID().toString();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("groupId", groupId);
        jsonObject.put("command", "create");
        nettyClient.send(jsonObject);
        System.out.println("创建事务组");

        currentGroupId.set(groupId);
        return groupId;
    }

    /**
     * 创建分支事务
     * @param groupId
     * @return
     */
    public static BatchTransaction createBatchTransaction(String groupId) {
        String transactionId = UUID.randomUUID().toString();
        BatchTransaction batchTransaction = new BatchTransaction(groupId, transactionId);
        BATCH_TRANSACION_MAP.put(groupId, batchTransaction);
        currentBatchTransaction.set(batchTransaction);
        addTransactionCount();
        System.out.println("创建分支事务");
        return batchTransaction;
    }

    /**
     * 注册事务
     * @param batchTransaction
     * @param isEnd
     * @param transactionStatus
     * @return
     */
    public static BatchTransaction registerBatchTransaction(BatchTransaction batchTransaction, Boolean isEnd, TransactionStatus transactionStatus) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("groupId", batchTransaction.getGroupId());
        jsonObject.put("transactionId", batchTransaction.getTransactionId());
        jsonObject.put("transactionType", transactionStatus);
        jsonObject.put("command", "add");
        jsonObject.put("isEnd", isEnd);
        jsonObject.put("transactionCount", GlobalTransactionManager.getTransactionCount());
        nettyClient.send(jsonObject);
        System.out.println("注册分支事务");
        return batchTransaction;
    }

    /**
     * 根据全局事务组id获取分支事务对象
     * @param groupId
     * @return
     */
    public static BatchTransaction getBatchTransaction(String groupId) {
        return BATCH_TRANSACION_MAP.get(groupId);
    }

    /**
     * 获取当前线程分支事务
     * @return
     */
    public static BatchTransaction getCurrent() {
        return currentBatchTransaction.get();
    }

    /**
     * 获取当前线程全局事务组id
     * @return
     */
    public static String getCurrentGroupId() {
        return currentGroupId.get();
    }

    /**
     * 设置当前线程全局事务组id
     * @param groupId
     */
    public static void setCurrentGroupId(String groupId) {
        currentGroupId.set(groupId);
    }

    /**
     * 获取当前线程分支事务数
     * @return
     */
    public static Integer getTransactionCount() {
        return transactionCount.get();
    }

    /**
     * 设置当前线程分支事务数
     * @param i
     */
    public static void setTransactionCount(int i) {
        transactionCount.set(i);
    }

    /**
     * 增加当前线程分支事务数
     * @return
     */
    public static Integer addTransactionCount() {
        int i = (transactionCount.get() == null ? 0 : transactionCount.get()) + 1;
        transactionCount.set(i);
        return i;
    }
}
